/**3. 无重复字符的最长子串 
 * - 给定一个字符串 s ，请你找出其中不含有重复字符的 最长子串 的长度。
 * - 示例：s = "abcabcbb"，输出3，因为无重复字符的最长子串是 "abc"
 */
export function lengthOfLongestSubstring(s: string = "pwwkew"): number {
    //方法2 - 哈希滑动窗口
    const map = new Map<string, number>()
    let length = 0
    let left = 0
    for (let right = 0; right < s.length; right++) {
        const c = s[right];
        const cIndex = map.get(c)
        if (cIndex !== undefined) {
            length = Math.max(length, right - left)
            while (left <= cIndex) {
                map.delete(s[left++]) //把left推进到重复字符的后面，重新开始
            }
        }
        map.set(c, right)
    }

    return Math.max(length, map.size)


    // /**窗口左边界 */
    // let left = 0
    // /**窗口右边界 */
    // let right = 0
    // /**最大窗口 */
    // let max = 0
    // while (right < s.length) {
    //     let temp = s.slice(left, right)
    //     if (temp.indexOf(s[right]) === -1) { //如果 s[right] 在当前窗口内 不存在
    //         right++ //右侧推进
    //         max = Math.max(max, right - left)//获取最大值
    //     } else {
    //         left++ //如果存在，那么只移动左边界 ，继续while循环判断s[right]是否存在
    //     }
    // }
    // return max
}
/**209. 长度最小的子数组
 * - 给定一个含有 n 个正整数的数组和一个正整数 target 
 * - 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ，并返回其长度。如果不存在符合条件的子数组，返回 0 。
 */
export function minSubArrayLen(target: number, nums: number[]): number {
    let left = 0
    let sum = 0
    let min = Infinity
    for (let right = 0; right < nums.length; right++) { //右窗口扩张
        sum += nums[right]
        //左窗口收缩，同时计算最小值
        while (sum >= target && left < nums.length) {
            console.log(left, right);
            min = Math.min(min, right - left + 1)
            sum -= nums[left++] //这一步如果缩小导致sum小于target了，for循环会加回来（原状态已经在上一行代码记录了）
        }
    }

    return min === Infinity ? 0 : min
}